/*
--------------------------------------------------------------------------------
- 文件：store.h

- 模块：st

- 作用：存储语法分析模块输出的：符号记录／块内容／重定位记录。
        不仅仅存储，还可以查询和修改已有内容。
        甚至可以把这个内部存储格式转储到 ELF 文件的功能加入本模块。
        进一步，可以填加读入 ELF 文件内容，转储为本内部格式。

- 依赖：严重依赖 area 模块。

- 记录：2004.11.23 建立，version 0.1 ：王明东
 
--------------------------------------------------------------------------------
*/

/* ---- 引用头文件 ---------------------------------------------------------- */
#include "asmtype.h"
#include "character.h"
#include "area.h"

/* ----- 宏定义 ------------------------------------------------------------- */

/* 非法值 */
#define  STORE_INVALID_ID       (0)
#define  SYMBOL_INVALID_ID      (0)
#define  SECTION_INVALID_ID     (0)

/* 块头部中的类型域 */
#define  ST_SEC_TYPE_NULL           (0)
#define  ST_SEC_TYPE_TEXT           (1)
#define  ST_SEC_TYPE_DATA           (2)
#define  ST_SEC_TYPE_BSS            (3)

#define  ST_SYM_TYPE_NOTYPE         (0)
#define  ST_SYM_TYPE_FILE           (1)
#define  ST_SYM_TYPE_SECTION        (2)
#define  ST_SYM_TYPE_OBJECT         (3)
#define  ST_SYM_TYPE_FUNCTION       (4)

#define  ST_SYM_BIND_NOBIND         (0)
#define  ST_SYM_BIND_LOCAL          (1)
#define  ST_SYM_BIND_GLOBAL         (2)
#define  ST_SYM_BIND_WEAK           (3)
#define  ST_SYM_BIND_EXTERN         (4)


/*
 *    TYPE_JMP : 指令 jmp 跳转到 lable, 使用 3 个字节表示相对偏移。
 *    TYPE_BRANCH : 指令 branch 跳转到 lable, 使用 2 个字节的相对偏移.
 *    TYPE_DOCTA : 用于使用 .octa 中使用 lable , 来表达绝对指针.
 *    现在还没有是用 addend 的类型.
 */
#define  ST_RLC_TYPE_NONE           (0)
#define  ST_RLC_TYPE_JMP            (1)
#define  ST_RLC_TYPE_BRANCH         (2)
#define  ST_RLC_TYPE_DOCTA          (3)



/* ---- 类型定义 ------------------------------------------------------------ */



/* 这个数据结构是给用户使用的，用于符号的添加、查找和修改操作 */
typedef  struct
{
    tetra *  name;     /* */
    tetra  type;              /* file, section, func, object  */
    tetra  bind;              /* local, global, weak          */
    
    tetra  shndx;                 /* 符号所在段               */
    octa  value;  /* 符号的偏移或其它意义     */
    octa  size;   /* 符号代表的数据所占的空间 */
} st_symbol_t;



/* 这是块的描述结构，用于一个块被创建时 */
typedef  struct
{
    tetra *  name;
    tetra  type;      /* code, data, bss  */
    tetra  align;     /* 指数／0 的个数   */
} st_section_t;

typedef  struct
{
    tetra  type;
    tetra  symbol_id;
    octa  offset;
    octa  addend;
} st_relocate_t;


/* ---- 函数原型声明 -------------------------------------------------------- */

/* 创建上下文，销毁上下文    */
tetra  st_init_context();
void  st_fini_context( tetra st_ct );

/* 针对符号的三种操作，添加、搜索、修改 */
tetra  st_add_symbol( tetra st_ct, st_symbol_t * p_st_sm );
tetra  st_search_symbol( tetra st_ct, st_symbol_t * p_st_sm );
tetra  st_modify_symbol( tetra st_ct, st_symbol_t * p_st_sm );

/* 块的创建         */
tetra  st_add_section( tetra st_ct, st_section_t * p_st_se );

/* 在某个块中添加数据       */
tetra  st_section_add_data( tetra st_ct, tetra sec_id, tetra len, void * buf );

/* 在某个块中添加重定位信息 */
tetra  st_section_add_relocate( tetra st_ct, tetra sec_id, st_relocate_t *  p_st_re );

